 /*
 * interface file for SWIG
 *
 * Copyright (c) 2012 Yongbo Tang
 *
 * This file is part of pylibMask.
 *
 * libMask is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * libMask is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with libMask.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 
 
 %module pylibMask
 %{
 /* Put header files here or function declarations like below */
 #include "../src/mask.h"
 %}
 
 %include "../src/msk_technology.h"
 %include "../src/mask.h"
 
 
 %typemap(in) PyObject *pyFunc {
  if (!PyCallable_Check($input)) {
      PyErr_SetString(PyExc_TypeError, "Need a callable object!");
      return NULL;
  }
  $1 = $input;
}

%inline %{

PyObject * pyFunc_sublayout[MSK_MAX_LAYOUTS];
static int num_cell = 0;

static void PyCallback_sublayout(int i)
{
   PyObject *func, *arglist;
   PyObject *result;
   
   //fprintf(stdout, "PyCallback: called num_cell: %d\n", i); //DEBUG   
   func = (PyObject *)(pyFunc_sublayout[i]);               // Get Python function
   //fprintf(stdout, "PyCallback: %p -> %p \n", pyFunc_sublayout[i], func); //DEBUG
   
   arglist = Py_BuildValue("(i)",i);             // Build argument list
   result = PyEval_CallObject(func,arglist);     // Call Python
   Py_DECREF(arglist);                           // Trash arglist
   Py_XDECREF(result);
  
   //fprintf(stdout, "PyCallback: result\n"); //DEBUG
   return; //void
}

int msk_add_sublayout(const char* name, PyObject * pyFunc){
  pyFunc_sublayout[num_cell] = (PyObject *)pyFunc;
  //pyFunc_sublayout = pyFunc;
  Py_XDECREF(pyFunc_sublayout[num_cell]);          /* Dispose of previous callback */
  Py_XINCREF(pyFunc);         /* Add a reference to new callback */  
  
  //fprintf(stdout, "called cell name: %s, %i, %p -> %p\n", name, num_cell, pyFunc, pyFunc_sublayout[num_cell]); //DEBUG
  //fprintf(stdout, "called function: %p\n", PyCallback_sublayout);//DEBUG
  
  num_cell++;
  //return msk_add_sublayout(name, &PyCallback_sublayout);
  return msk_add_sublayout(name, &PyCallback_sublayout);
}

%}

%extend Layer 
{//to add manipulate functions.
  Layer(int number, const char *name, int color, int visible, double eps){
    struct Layer *lr = (Layer *) malloc(sizeof(Layer));
    lr->number = number;
    lr->name = name;
    lr->color = color;
    lr->visible = visible;
    lr->eps = eps;
    return lr;
  }
  ~Layer(){
    free($self);
  }
  char *__str__(){
    static char temp[256];
    sprintf(temp, "%d, %s, %d, %d, %e\n", $self->number, $self->name, $self->color, $self->visible, $self->eps);
    return &temp[0];
  }
}

//support input list as array.
%typemap(in) double * {
  /* Check if is a list */
  if (PyList_Check($input)) {
    int size = PyList_Size($input);
    int i = 0;
    $1 = (double *) malloc(size*sizeof(double));
    for (i = 0; i < size; i++) {
      PyObject *o = PyList_GetItem($input,i);
      if (PyFloat_Check(o))
        $1[i] = PyFloat_AsDouble(o);
      else 
      {
        if (PyInt_Check(o))
          $1[i] = (double)PyInt_AsLong(o);      
        else
        {
        PyErr_SetString(PyExc_TypeError,"list must contain float numbers");
        free($1);
        return NULL;
        }
      }
    }
  } else {
    PyErr_SetString(PyExc_TypeError,"not a list");
    return NULL;
  }
}

%typemap(freearg) double * {
  free($1);
}